package com.example.war;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

import android.graphics.Bitmap;
import android.opengl.GLUtils;

public class Quad {
    private FloatBuffer   mVertexBuffer;
    private FloatBuffer   mTexCoordsBuffer;
    private FloatBuffer   mColorBuffer;
    int mTexId = -1;
    public int mWidth;
    public int mHeight;
    float mTexCoordX;
    float mTexCoordY;
    float mTexCoordW;
    float mTexCoordH;
    private boolean mIsTransparent;
    
    public Quad(boolean transparent) {    
        setTexCoods(0, 0, 1, 1); // default use the full image as the texture

        if (transparent) {
            float[] colors = {
                    1.0f, 1.0f, 1.0f, 0.1f,
                    1.0f, 1.0f, 1.0f, 0.1f,
                    1.0f, 1.0f, 1.0f, 1.0f,
                    1.0f, 1.0f, 1.0f, 1.0f,
            };

            mColorBuffer = createFloatBuf(colors);
        }

        mIsTransparent = transparent;
    }
    
    public Quad(int w, int h,int pow,int poh) {    
        
        setTexCoodsNoZoom(0, 0, w, h,pow,poh); // default use the full image as the texture
            float[] colors = {
                    1.0f, 1.0f, 1.0f, 0.1f,
                    1.0f, 1.0f, 1.0f, 0.1f,
                    1.0f, 1.0f, 1.0f, 1.0f,
                    1.0f, 1.0f, 1.0f, 1.0f,
            };
            mColorBuffer = createFloatBuf(colors);
        }

    private float mAlpha;
    public void setAlpha(float alpha) {
        mAlpha = alpha;
        mIsTransparent = true;
//        if (alpha != 1) {
//            float[] colors = {
//                    1.0f, 1.0f, 1.0f, alpha,
//                    1.0f, 1.0f, 1.0f, alpha,
//                    1.0f, 1.0f, 1.0f, alpha,
//                    1.0f, 1.0f, 1.0f, alpha,
//            };
//    
//            mColorBuffer = createFloatBuf(colors);
//            mIsTransparent = true;
//        } else {
//            mIsTransparent = false;
//        }
    }

    public void setTexture(GL10 gl, Bitmap bitmap, boolean mipmap) {
        if (mTexId == -1) {
            int[] textures = new int[1];
            gl.glGenTextures(1, textures, 0);
            mTexId = textures[0];
        }
        
        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTexId);
        
        if (mipmap) {
            if(gl instanceof GL11) {
                gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL11.GL_TRUE);
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
            } else {
                Utils.buildMipmap(gl, bitmap);
            }
        } else {
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            int nextPow2W = Utils.nextPow2(width);
            int nextPow2H = Utils.nextPow2(height);
//            if (width != nextPow2W || height != nextPow2H) {
//                gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, nextPow2W, nextPow2H, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_SHORT_4_4_4_4, null);
//                GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, bitmap);
//            } else {
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
            //}
        }

        setTexture(gl, mTexId);
    }
    
    public void setTextureNoZoom(GL10 gl, Bitmap bmp, int type) {
        if (mTexId == -1) {
            int[] textures = new int[1];
            gl.glGenTextures(1, textures, 0);
            mTexId = textures[0];
        }
        
        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTexId);

        if (type == -1)
            //GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
            GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, bmp);
        else
           // GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
            GLUtils.texSubImage2D(GL10.GL_TEXTURE_2D, 0, 0, 0, bmp);
           // GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, bmp, type, 0);

        setTexture(gl, mTexId);
    }

    public void deleteTexture(GL10 gl) {
        int[] textures = new int[1];
        textures[0] = mTexId;
        gl.glDeleteTextures(1, textures, 0);
    }

    public void setTexture(GL10 gl, int texId) {
        gl.glEnable(GL10.GL_TEXTURE_2D);
        gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
        mTexId = texId;
    }

    private FloatBuffer createFloatBuf(float[] floatArray) {
        ByteBuffer vbb = ByteBuffer.allocateDirect(floatArray.length*4);
        vbb.order(ByteOrder.nativeOrder());

        FloatBuffer floatBuf = vbb.asFloatBuffer();
        floatBuf.put(floatArray);
        floatBuf.position(0);

        return floatBuf;
    }

    public void setSize(float w, float h) {
        setSize((int)w, (int)h);
    }

    public void setSize(int w, int h) {
        if (mWidth == w && mHeight == h)
            return;
        mWidth = w;
        mHeight = h;
        float hafW = (float)(w>>1);
        float hafH = (float)(h>>1);
        float[] vertices = {
                -hafW,  -hafH,
                 hafW,  -hafH,
                 hafW,   hafH,
                -hafW,   hafH,
        };

        if (mVertexBuffer != null)
            mVertexBuffer.clear();

        mVertexBuffer = createFloatBuf(vertices);
    }
    
    public void setTexCoods(float x, float y, float w, float h) {
        if (mTexCoordX == x && mTexCoordY == y &&
            mTexCoordW == w && mTexCoordH == h) {
            return;
        }

        mTexCoordX = x;
        mTexCoordY = y;
        mTexCoordW = w;
        mTexCoordH = h;

        float[] texCoods = {
                 x,    y+h,
                 x+w,  y+h,
                 x+w,  y,
                 x,    y,
        };

       if (mTexCoordsBuffer != null)
           mTexCoordsBuffer.clear();

       mTexCoordsBuffer = createFloatBuf(texCoods);
    }
    
       public void setTexCoodsNoZoom(float x, float y, float w, float h,float pow,float poh) {
            if (mTexCoordX == x && mTexCoordY == y &&
                mTexCoordW == w && mTexCoordH == h) {
                return;
            }

            mTexCoordX = x;
            mTexCoordY = y;
            mTexCoordW = w;
            mTexCoordH = h;

            float[] texCoods = {
                     x,    y+ h/poh,
                     x+w/pow,  y+h/poh,
                     x+w/pow,  y,
                     x,    y,
            };

           if (mTexCoordsBuffer != null)
               mTexCoordsBuffer.clear();

           mTexCoordsBuffer = createFloatBuf(texCoods);
        }
    
    public void draw(GL10 gl, float xRotAngle, float x, float y, float z) {
        draw(gl, xRotAngle, x, y, z, false);
    }

    public void draw(GL10 gl, float xRotAngle, float x, float y, float z, boolean blend) {
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glPushMatrix();

        gl.glTranslatef(x, y, z);
        if (xRotAngle != 0) {
            gl.glRotatef(xRotAngle, -1.0f, 0.0f, 0.0f);
        }
        
        if (mIsTransparent) {
            gl.glEnable(GL10.GL_BLEND);
            gl.glBlendFunc(GL10.GL_DST_ALPHA, GL10.GL_ZERO);
            //gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_DECAL);GL_TEXTURE_ENV_COLOR
            gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);
            //gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
            //gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
            gl.glShadeModel(GL10.GL_SMOOTH);
            gl.glColor4f(1f, 1f, 1f, mAlpha);
        } else {
            gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
        }
        if (blend) {
            gl.glEnable(GL10.GL_BLEND);
            gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
        }
        gl.glActiveTexture(GL10.GL_TEXTURE0);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glVertexPointer(2, GL10.GL_FLOAT, 0, mVertexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexCoordsBuffer);

        gl.glEnable(GL10.GL_TEXTURE_2D);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTexId);

        gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);

        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisable(GL10.GL_TEXTURE_2D);

        if (mIsTransparent) {
            gl.glDisable(GL10.GL_BLEND);
            gl.glShadeModel(GL10.GL_FLAT);
            gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
        }
        if (blend)
            gl.glDisable(GL10.GL_BLEND);

        gl.glPopMatrix();
    }
}